package com.netease.qa.web.controller;

import com.netease.qa.biz.dto.ProjectDTO;
import com.netease.qa.biz.dto.TestCaseDTO;
import com.netease.qa.biz.enums.RequestType;
import com.netease.qa.biz.enums.TestCaseStatus;
import com.netease.qa.biz.service.EngineService;
import com.netease.qa.biz.service.ProjectService;
import com.netease.qa.biz.service.TestCaseService;
import com.netease.qa.web.utils.ServiceResult;
import com.netease.qa.web.utils.UserUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * @author zoudongdong
 * @date 2018/3/10
 */
@Controller
public class EngineController {

    private static Logger log = LoggerFactory.getLogger(EngineController.class);

    @Resource
    private EngineService engineService;
    @Resource
    private ProjectService projectService;
    @Resource
    private TestCaseService testCaseService;

    @RequestMapping(value = "/validateBeforeExecute", method = RequestMethod.POST)
    @ResponseBody
    public ServiceResult validateBeforeExecute(@RequestBody TestCaseDTO testCaseDTO, HttpServletRequest request) {
        log.info("******validateBeforeExecute******");

        String currentUserId = UserUtils.getCurrentLoginUserId(request);
        if (!UserUtils.ifUserJoinedTeam(currentUserId, testCaseDTO.getTeamId())) {
            return ServiceResult.successMsg("您不属于该团队,没有权限执行该测试用例!!!");
        }
        //如果用例非有效状态,则不能更新用例
        TestCaseDTO testCase = testCaseService.getTestCaseDetail(testCaseDTO.getCaseId());
        if (testCase.getStatus() != TestCaseStatus.Valid.getValue()) {
            return ServiceResult.successMsg("该用例已删除,不能执行该测试用例!!!");
        }
        return ServiceResult.successMsg("验证通过");
    }

    @RequestMapping(value = "/executeTestCase", method = RequestMethod.POST)
    @ResponseBody
    public ServiceResult executeTestCase(@RequestBody TestCaseDTO testCaseDTO) {
        log.info("******executeTestCase******");
        String requestType = testCaseDTO.getRequestType();
        String url = getUrl(testCaseDTO);
        String jsonPathCheckPoint = testCaseDTO.getJsonPathCheckPoint();
        Map<String, Object> headerMap = genMap(testCaseDTO.getHeaderKeys(), testCaseDTO.getHeaderValues());
        Map<String,String> result;

        try {
            if (requestType.equals(RequestType.GET.getDesc())) {
                String paramKeys = testCaseDTO.getParamKeys();
                String paramValues = testCaseDTO.getParamValues();

                Map<String, Object> paramMap = genMap(paramKeys, paramValues);

                if (jsonPathCheckPoint.equals("")) {
                    result = engineService.doGetMethod(url, headerMap, paramMap);
                } else {
                    result = engineService.doGetMethodAndValidateJsonPath(url, headerMap, paramMap, jsonPathCheckPoint);
                }
            } else if (requestType.equals(RequestType.POST.getDesc())) {
                String paramRaw = testCaseDTO.getParamRaw();

                //post请求的默认是json格式的数据
                headerMap.put("Content-Type", "application/json");

                if(jsonPathCheckPoint.equals("")){
                    result = engineService.doPostMethod(url, headerMap, paramRaw);
                }else {
                    result = engineService.doPostMethodAndValidateJsonPath(url,headerMap,paramRaw,jsonPathCheckPoint);
                }
            } else {
                result = new HashMap<String, String>();
                result.put("responseBody","不支持的请求类型!!!");
            }
        } catch (Exception e) {
            //保存异常信息
            StringWriter sw = null;
            PrintWriter pw = null;
            log.error(e.getMessage(), e);
            try {
                sw = new StringWriter();
                pw = new PrintWriter(sw);
                e.printStackTrace(pw);
                String responseBody = sw.toString().replace("at ", "<br/>at ");
                result = new HashMap<String, String>();
                result.put("responseBody",responseBody);
            } finally {
                if (sw != null) {
                    try {
                        sw.close();
                    } catch (IOException e1) {
                        log.error(e1.getMessage(), e1);
                    }
                }
                if (pw != null) {
                    pw.close();
                }
            }
        }
        return ServiceResult.success(result);
    }

    public String getUrl(TestCaseDTO testCaseDTO) {
        StringBuilder sb = new StringBuilder();
        sb.append("http://");
        ProjectDTO projectDTO = projectService.getProjectDetail(testCaseDTO.getProjectId());
        sb.append(projectDTO.getIp() + ":" + projectDTO.getPort());
        sb.append(testCaseDTO.getUrl());
        return sb.toString();
    }

    /**
     * 返回map
     *
     * @param originKeys   ","号分隔的字符串
     * @param originValues ","号分隔的字符串
     * @return
     */
    public Map<String, Object> genMap(String originKeys, String originValues) {
        String[] keysAttr = originKeys.split(",");
        String[] valuesAttr = originValues.split(",");

        Map<String, Object> map = new HashMap<String, Object>();
        for (int i = 0; i < keysAttr.length; i++) {
            map.put(keysAttr[i], valuesAttr[i]);
        }
        return map;
    }
}
